package com.example.kafka.controller;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.kafka.service.TransactionRiskyService;
import com.example.kafka.service.TransactionSafeService;

import lombok.extern.slf4j.Slf4j;

/**
 * 没有数据不一致风险的控制器示例
 * 演示正确使用事务管理确保数据一致性
 */
@Slf4j
@RestController
@RequestMapping("/api/transaction/safe")
public class TransactionSafeController {

    @Autowired
    private TransactionSafeService transactionSafeService;

    @Autowired
    private TransactionRiskyService transactionRiskyService;

    /**
     * 安全示例1：创建用户和账户（有事务保护）
     * GET
     * /api/transaction/safe/create-user-account?username=test&email=test@example.com&fullName=Test
     * User
     */
    @GetMapping("/create-user-account")
    public ResponseEntity<String> createUserWithAccount(
            @RequestParam String username,
            @RequestParam String email,
            @RequestParam String fullName) {

        log.info("请求创建用户和账户（有事务保护）: {}", username);

        try {
            String result = transactionSafeService.createUserWithAccountSafe(username, email, fullName);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("创建用户和账户失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("创建失败: " + e.getMessage());
        }
    }

    /**
     * 安全示例2：转账操作（有事务保护）
     * GET /api/transaction/safe/transfer?fromUserId=1&toUserId=2&amount=100.00
     */
    @GetMapping("/transfer")
    public ResponseEntity<String> transferMoney(
            @RequestParam Long fromUserId,
            @RequestParam Long toUserId,
            @RequestParam BigDecimal amount) {

        log.info("请求转账操作（有事务保护）: 从用户{}转账{}到用户{}", fromUserId, amount, toUserId);

        try {
            String result = transactionSafeService.transferMoneySafe(fromUserId, toUserId, amount);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("转账操作失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("转账失败: " + e.getMessage());
        }
    }

    /**
     * 安全示例3：批量更新用户状态（有事务保护）
     * POST /api/transaction/safe/batch-update-status
     * Body: {"userIds": [1, 2, 3], "newStatus": "INACTIVE"}
     */
    @PostMapping("/batch-update-status")
    public ResponseEntity<String> batchUpdateUserStatus(
            @RequestBody BatchUpdateRequest request) {

        log.info("请求批量更新用户状态（有事务保护）: {} 个用户", request.getUserIds().size());

        try {
            String result = transactionSafeService.batchUpdateUserStatusSafe(
                    request.getUserIds(), request.getNewStatus());
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("批量更新用户状态失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("批量更新失败: " + e.getMessage());
        }
    }

    /**
     * 安全示例4：复杂业务操作（有事务保护）
     * GET /api/transaction/safe/complex-operation?userId=1&amount=50.00
     */
    @GetMapping("/complex-operation")
    public ResponseEntity<String> complexBusinessOperation(
            @RequestParam Long userId,
            @RequestParam BigDecimal amount) {

        log.info("请求复杂业务操作（有事务保护）: 用户{}, 金额{}", userId, amount);

        try {
            String result = transactionSafeService.complexBusinessOperationSafe(userId, amount);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("复杂业务操作失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("复杂业务操作失败: " + e.getMessage());
        }
    }

    /**
     * 安全示例5：编程式事务管理
     * GET /api/transaction/safe/programmatic-transaction?userId=1&amount=25.00
     */
    @GetMapping("/programmatic-transaction")
    public ResponseEntity<String> programmaticTransaction(
            @RequestParam Long userId,
            @RequestParam BigDecimal amount) {

        log.info("请求编程式事务操作: 用户{}, 金额{}", userId, amount);

        try {
            String result = transactionSafeService.programmaticTransactionExample(userId, amount);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("编程式事务操作失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("编程式事务操作失败: " + e.getMessage());
        }
    }

    /**
     * 安全示例6：只读事务
     * GET /api/transaction/safe/read-only-transaction?userId=1
     */
    @GetMapping("/read-only-transaction")
    public ResponseEntity<String> readOnlyTransaction(@RequestParam Long userId) {
        log.info("请求只读事务操作: 用户{}", userId);

        try {
            String result = transactionSafeService.readOnlyTransactionExample(userId);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("只读事务操作失败: {}", e.getMessage());
            return ResponseEntity.internalServerError().body("只读事务操作失败: " + e.getMessage());
        }
    }

    /**
     * 演示数据一致性保护的测试接口
     * GET /api/transaction/safe/demo-data-consistency
     */
    @GetMapping("/demo-data-consistency")
    public ResponseEntity<String> demoDataConsistency() {
        log.info("开始演示数据一致性保护");

        StringBuilder result = new StringBuilder();
        result.append("=== 数据一致性保护演示 ===\n\n");

        // 演示1：创建用户和账户
        result.append("1. 创建用户和账户（有事务保护）:\n");
        try {
            String createResult = transactionSafeService.createUserWithAccountSafe(
                    "safe_user_" + System.currentTimeMillis(),
                    "safe@example.com",
                    "Safe User");
            result.append("   结果: ").append(createResult).append("\n");
        } catch (Exception e) {
            result.append("   结果: 失败 - ").append(e.getMessage()).append("\n");
        }

        result.append("\n2. 转账操作（有事务保护）:\n");
        try {
            String transferResult = transactionSafeService.transferMoneySafe(1L, 2L, new BigDecimal("100.00"));
            result.append("   结果: ").append(transferResult).append("\n");
        } catch (Exception e) {
            result.append("   结果: 失败 - ").append(e.getMessage()).append("\n");
        }

        result.append("\n3. 批量更新状态（有事务保护）:\n");
        try {
            String batchResult = transactionSafeService.batchUpdateUserStatusSafe(
                    Arrays.asList(1L, 2L, 3L), "INACTIVE");
            result.append("   结果: ").append(batchResult).append("\n");
        } catch (Exception e) {
            result.append("   结果: 失败 - ").append(e.getMessage()).append("\n");
        }

        result.append("\n4. 编程式事务管理:\n");
        try {
            String programmaticResult = transactionSafeService.programmaticTransactionExample(1L,
                    new BigDecimal("25.00"));
            result.append("   结果: ").append(programmaticResult).append("\n");
        } catch (Exception e) {
            result.append("   结果: 失败 - ").append(e.getMessage()).append("\n");
        }

        result.append("\n5. 只读事务:\n");
        try {
            String readOnlyResult = transactionSafeService.readOnlyTransactionExample(1L);
            result.append("   结果: ").append(readOnlyResult).append("\n");
        } catch (Exception e) {
            result.append("   结果: 失败 - ").append(e.getMessage()).append("\n");
        }

        result.append("\n=== 安全特性说明 ===\n");
        result.append("- 使用@Transactional注解确保事务边界\n");
        result.append("- 任何步骤失败都会自动回滚整个事务\n");
        result.append("- 保证数据的一致性和完整性\n");
        result.append("- 支持只读事务提高性能\n");
        result.append("- 支持编程式事务管理提供更细粒度控制\n");

        return ResponseEntity.ok(result.toString());
    }

    /**
     * 对比演示：同时测试有事务和无事务的差异
     * GET /api/transaction/safe/compare-transaction-behavior
     */
    @GetMapping("/compare-transaction-behavior")
    public ResponseEntity<String> compareTransactionBehavior() {
        log.info("开始对比演示事务行为");

        StringBuilder result = new StringBuilder();
        result.append("=== 事务行为对比演示 ===\n\n");

        result.append("测试场景：创建用户和账户，模拟中间步骤失败\n\n");

        // 测试有事务保护的情况
        result.append("【有事务保护】:\n");
        for (int i = 1; i <= 3; i++) {
            try {
                String createResult = transactionSafeService.createUserWithAccountSafe(
                        "safe_test_" + i + "_" + System.currentTimeMillis(),
                        "safe_test_" + i + "@example.com",
                        "Safe Test User " + i);
                result.append("   尝试 ").append(i).append(": ").append(createResult).append("\n");
            } catch (Exception e) {
                result.append("   尝试 ").append(i).append(": 失败 - ").append(e.getMessage()).append("\n");
            }
        }

        result.append("\n【无事务保护】:\n");
        for (int i = 1; i <= 3; i++) {
            try {
                String createResult = transactionRiskyService.createUserWithAccountRisky(
                        "risky_test_" + i + "_" + System.currentTimeMillis(),
                        "risky_test_" + i + "@example.com",
                        "Risky Test User " + i);
                result.append("   尝试 ").append(i).append(": ").append(createResult).append("\n");
            } catch (Exception e) {
                result.append("   尝试 ").append(i).append(": 失败 - ").append(e.getMessage()).append("\n");
            }
        }

        result.append("\n=== 对比结果分析 ===\n");
        result.append("有事务保护：失败时所有操作都会回滚，数据保持一致性\n");
        result.append("无事务保护：失败时已执行的操作不会回滚，可能导致数据不一致\n");

        return ResponseEntity.ok(result.toString());
    }

    /**
     * 请求体类
     */
    public static class BatchUpdateRequest {
        private List<Long> userIds;
        private String newStatus;

        public List<Long> getUserIds() {
            return userIds;
        }

        public void setUserIds(List<Long> userIds) {
            this.userIds = userIds;
        }

        public String getNewStatus() {
            return newStatus;
        }

        public void setNewStatus(String newStatus) {
            this.newStatus = newStatus;
        }
    }
}
